package org.ovhoo.zonfig;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;


import org.ovhoo.io.ZBufferedWriter;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;


/**
 * Load and store a configuration to a file using a defined xml format
 * @author mzalim
 * @version 0.1.0
 *
 */
public class Zonfig {
	
	private static final String XSDFILEPATH = "res/zonfig.xsd";
	//attributes
	private String filePath;		//The path of the configuration file
	
	private ArrayList<Category> categories ; //Decoded categories
	//private static ZonfigHandler zonfigHandler;
	private ArrayList<Type> types;
	
	/**
	 * Default constructor
	 * @param filePath : The complete path of the configuration file
	 */
	public Zonfig(String filePath){
		this.filePath = filePath;
	}
	
	/**
	 * This procedure loads and decodes the configuration file
	 */
	public boolean decode(){
		boolean _result = true;					//indicate if the operation succedded
		//RFile _configFile = new RFile(this.filePath); //open the file to decode
		
		this.categories = null;
		this.types = null;
		ZonfigHandler _zonfigHandler = new ZonfigHandler();
		ZonfigErrorHandler _zonfigErrorHandler = new ZonfigErrorHandler();
		XMLReader _xmlReader;
        
        
        
        try {
        	_xmlReader = XMLReaderFactory.createXMLReader();
        	
        	
        	_xmlReader.setErrorHandler(_zonfigErrorHandler);
        	_xmlReader.setContentHandler(_zonfigHandler);
        	
        	_xmlReader.setFeature("http://xml.org/sax/features/validation",true);
        	_xmlReader.setFeature("http://apache.org/xml/features/validation/schema",true);

        	_xmlReader.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaSource", 
            "file:" + XSDFILEPATH);

        	_xmlReader.parse(this.filePath);
        } catch (IOException e) {
                // TODO Auto-generated catch block
            e.printStackTrace();
            _result = false;
        } catch (SAXException e) {
                // TODO Auto-generated catch block
            e.printStackTrace();
            _result = false;
        }
        if (_zonfigErrorHandler.isValide()){
        	this.categories = _zonfigHandler.getCategories();
        	this.types = _zonfigHandler.getTypes();
        	return _result;
        }
        else{
        	this.categories = null;
        	return false;
        }
	}
	
	/**
	 * Store the current configuration to the indicated file
	 * @param filePath : The path of the new configuration file
	 */
	public boolean store(String filePath){
		//chnge the configuration file path
		this.setConfigurationFilePath(filePath);
		
		File _file = new File(filePath);
		ZBufferedWriter _bufferWriter;
		
		try {
			_bufferWriter = new ZBufferedWriter(_file);
			this.writeContent(_bufferWriter);
			_bufferWriter.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.err.println("Error oppening the file :" + _file.getPath());
			return false;
		}
		
		return true;
	}
	
	/**
	 * write the configuration file
	 * @param bufferWriter : the configuration file buffer writer
	 */
	private void writeContent(ZBufferedWriter bufferWriter){

		bufferWriter.writeln("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		bufferWriter.writeln("<zonfig>");
		
		if (this.types != null){
			bufferWriter.writeln("	<types>");
			
			Iterator<Type> _itTypes = this.types.iterator();
			Type _type;
			while(_itTypes.hasNext()){
				_type = _itTypes.next();
				_type.writeContent(bufferWriter, "		");
				
			}
			
			bufferWriter.writeln("	</types>");
		}
		if (this.categories != null){
			Iterator<Category> _itCategories = this.categories.iterator();
			Category _category;
			while(_itCategories.hasNext()){
				_category = _itCategories.next();
				_category.writeContent(bufferWriter, "	");
				
			}
		}
		
		bufferWriter.writeln("</zonfig>");
	}
	
	/**
	 * Change the path of the configuration file
	 * @param filePath : The path of the new configuration file
	 */
	public void setConfigurationFilePath(String filePath){
		this.filePath = filePath;
	}
	
	/**
	 * Returns the path of the configuration file
	 * @return The path of the configuration file
	 */
	public String getConfigurationFilePath(){
		return this.filePath;
	}
	
	
	
	
	
	//main entry
	public static void main(String args[]){
		Zonfig _zonfig = new Zonfig("zonfig.xml");
		_zonfig.decode();
		_zonfig.store("stored.xml");
		
	}
}
